package top.fate.controller;

import com.alibaba.fastjson.JSON;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.GetIndexRequest;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import top.fate.entity.EsData;
import top.fate.entity.FileData;
import top.fate.until.FileReading;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

@RestController
@RequestMapping(value = "fullTextSearch")
public class FullTextSearchController {
    @Autowired
    private ElasticsearchRestTemplate elasticsearchRestTemplate;
    @Autowired
    private RestHighLevelClient restHighLevelClient;

    private SearchRequest request = new SearchRequest("reading");

    //创建一个索引库
    @PutMapping("addIndex")
    public ResponseEntity addIndex() {
        elasticsearchRestTemplate.createIndex(EsData.class);
        elasticsearchRestTemplate.putMapping(EsData.class);
        return ResponseEntity.ok(200);
    }

    //删除索引库
    @DeleteMapping("deleteIndex")
    public ResponseEntity deleteIndex() throws IOException {
        // 1.创建Request对象
        DeleteIndexRequest request = new DeleteIndexRequest("reading");
        // 2.发送请求
        restHighLevelClient.indices().delete(request, RequestOptions.DEFAULT);
        return ResponseEntity.ok(200);
    }

    //将文档数据添加到es
    @PutMapping("add")
    public ResponseEntity addReading() throws IOException {
        FileReading fileReading = new FileReading();
        BulkRequest request = new BulkRequest();
        List<FileData> fileName = fileReading.getFileName();
        for (FileData fileData : fileName) {
            request.add(new IndexRequest("reading")
                    .id(fileData.getId())
                    .source(JSON.toJSONString(fileData), XContentType.JSON));
            System.out.println(fileData.getId());
            restHighLevelClient.bulk(request, RequestOptions.DEFAULT);
        }
        return ResponseEntity.ok("添加成功：200");
    }

    //查询es中所有数据
    @GetMapping("getAll")
    public ResponseEntity<List> getAll() throws IOException {
        // 1.准备Request
        SearchRequest request = new SearchRequest("reading");
        // 2.准备DSL
        request.source()
                .query(QueryBuilders.matchAllQuery());
        // 3.发送请求
        SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);
        // 4.解析响应
        List<FileData> list = handleResponse(response);
        //返回解析结果
        return ResponseEntity.ok(list);
    }

    //根据条件进行查询
    @GetMapping("getQuery")
    public ResponseEntity getQuery(String querya ,String queryb ) throws IOException {
        // 2.准备DSL
        request.source()
                .query(QueryBuilders.matchQuery(querya, queryb));
        // 3.发送请求
        SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);
        // 4.解析响应
        List<FileData> list = handleResponse(response);
        //返回解析结果
        return ResponseEntity.ok(list);
    }


    @GetMapping("getQueryAll")
    public ResponseEntity getQueryAll(String query) throws IOException {
        // 2.准备DSL
        request.source()
                .query(QueryBuilders.multiMatchQuery(query, "name", "readcon"));
        // 3.发送请求
        SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);
        // 4.解析响应
        List<FileData> list = handleResponse(response);
        //返回解析结果
        return ResponseEntity.ok(list);
    }


    //判断索引库是否存在
    @GetMapping("tested")
    ResponseEntity testExistsHotelIndex() throws IOException {
        // 1.创建Request对象
        GetIndexRequest request = new GetIndexRequest("reading");
        // 2.发送请求
        boolean exists = restHighLevelClient.indices().exists(request, RequestOptions.DEFAULT);
        // 3.输出
        System.err.println(exists ? "索引库已经存在！" : "索引库不存在！");
        return ResponseEntity.ok(exists ? "索引库已经存在！" : "索引库不存在！");
    }

    //根据条件对文档名字和内容进行匹配
    @GetMapping("queryAll")
    public ResponseEntity queryAll(String query) throws IOException {
        request.source()
                .query(QueryBuilders.boolQuery().must(QueryBuilders.matchQuery("name",query))
                                                .must(QueryBuilders.matchQuery("readcon",query)));
        SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);
        List<FileData> list = handleResponse(response);
        return ResponseEntity.ok(list);
    }

    //解析获取的es结果
    private List<FileData> handleResponse(SearchResponse response) {
        // 4.解析响应
        SearchHits searchHits = response.getHits();
        // 4.1.获取总条数
        long total = searchHits.getTotalHits().value;
        System.out.println("共搜索到" + total + "条数据");
        // 4.2.文档数组
        SearchHit[] hits = searchHits.getHits();
        //创建一个list数组
        List<FileData> list = new ArrayList<>();
        // 4.3.遍历
        for (SearchHit hit : hits) {
            // 获取文档source
            String json = hit.getSourceAsString();
            // 反序列化
            FileData fileData = JSON.parseObject(json, FileData.class);
            list.add(fileData);
          //  System.out.println("filDate = " + fileData);
        }
        return list;
    }
}
